#! /bin/sh

cleanup () {
  erl -pa ../src -sname fragmentron_killah -eval '
    "fragmentron_killah@" ++ Host = atom_to_list (node ()),
    Other = list_to_atom ("fragmentron_remove_node_test1@" ++ Host),
    MoreOther = list_to_atom ("fragmentron_remove_node_test2@" ++ Host),
    rpc:call (Other, erlang, halt, []),
    rpc:call (MoreOther, erlang, halt, [])
  ' -noshell -noinput -s erlang halt 

  rm -rf Mnesia*
}

rm -rf Mnesia*

erl -pa ../src -sname fragmentron_remove_node_test1 -s mnesia \
    -eval '
  mnesia:change_table_copy_type (schema, node (), disc_copies),
  timer:sleep (30000)'  \
  -s erlang halt -noshell -noinput &

erl -pa ../src -sname fragmentron_remove_node_test2 -s mnesia \
    -eval '
  "fragmentron_remove_node_test2@" ++ Host = atom_to_list (node ()),
  Self = node (),
  Other = list_to_atom ("fragmentron_remove_node_test1@" ++ Host),
  mnesia:change_config (extra_db_nodes, [ Other ]),
  mnesia:change_table_copy_type (schema, node (), disc_copies),
  timer:sleep (30000)'  \
  -s erlang halt -noshell -noinput &

sleep 1

erl -pa ../src -sname fragmentron_remove_node_test3 -s mnesia -eval '
  "fragmentron_remove_node_test3@" ++ Host = atom_to_list (node ()),
  Self = node (),
  Other = list_to_atom ("fragmentron_remove_node_test1@" ++ Host),
  MoreOther = list_to_atom ("fragmentron_remove_node_test2@" ++ Host),
  pong = net_adm:ping (Other),
  pong = net_adm:ping (MoreOther),
  { ok, Nodes } = mnesia:change_config (extra_db_nodes, [ Other, MoreOther ]),
  mnesia:change_table_copy_type (schema, node (), disc_copies),
  timer:sleep (1000),

  { atomic, ok } = 
    fragmentron:create_table (warez,
                              [ { frag_properties, 
                                  [ { node_pool, 
                                      [ node (), Other, MoreOther ] }, 
                                    { n_fragments, 2 }, 
                                    { n_disc_copies, 2 } ] } ]),

  { aborted, bad_copy_spec } = 
    fragmentron:create_table (flass, 
                              [ { frag_properties, [ 
                                    { n_disc_only_copies, 1 },
                                    { n_disc_copies, 1 },
                                    { n_ram_copies, 1 },
                                    { foreign_key, { warez, key } } ] } ] ),

  { atomic, ok } = 
    fragmentron:create_table (flass, 
                              [ { frag_properties, [ 
                                    { n_disc_only_copies, 2 },
                                    { n_disc_copies, 0 },
                                    { foreign_key, { warez, key } } ] } ] ),

  mnesia:subscribe (system),
  true = lists:member (MoreOther, mnesia:table_info (warez, disc_copies)),
  true = lists:member (MoreOther, mnesia:table_info (flass, disc_only_copies)),
  true = fragmentron:remove_node (warez, MoreOther),

  receive { mnesia_system_event, 
            { mnesia_user, { fragmentron, del_node, warez, MoreOther } } } -> 
    ok 
  after 0 -> exit (nomsg)
  end,

  receive { mnesia_system_event, 
            { mnesia_user, { fragmentron, del_node, flass, MoreOther } } } -> 
    exit (badmsg)
  after 0 -> 
    ok
  end,

  receive { mnesia_system_event, 
            { mnesia_user, 
              { fragmentron, del_table_copy, warez, MoreOther } } } -> ok 
  after 0 -> exit (nomsg_2)
  end,

  receive { mnesia_system_event, 
            { mnesia_user, 
              { fragmentron, del_table_copy, flass, MoreOther } } } -> ok 
  after 0 -> exit (nomsg_3)
  end,

  receive { mnesia_system_event, 
            { mnesia_user, 
              { fragmentron, add_table_copy, warez, N } } } 
    when N =/= MoreOther -> ok 
  after 0 -> exit (nomsg_4)
  end,

  receive { mnesia_system_event, 
            { mnesia_user, 
              { fragmentron, add_table_copy, flass, N2 } } } 
    when N2 =/= MoreOther -> ok 
  after 0 -> exit (nomsg_5)
  end,
mnesia:system_info (),

  { [ Other, Self ], [ Other, Self ] } = 
    { lists:sort (mnesia:table_info (warez, disc_copies)), 
      lists:sort (mnesia:table_info (warez_frag2, disc_copies)) },

  { [ Other, Self ], [ Other, Self ] } = 
    { lists:sort (mnesia:table_info (flass, disc_only_copies)),
      lists:sort (mnesia:table_info (flass_frag2, disc_only_copies)) },

  false = fragmentron:remove_node (warez, MoreOther),

  receive { mnesia_system_event, 
            { mnesia_user, { fragmentron, _, warez, _ } } } -> exit (badmsg_2)
  after 0 -> ok
  end,

  receive { mnesia_system_event, 
            { mnesia_user, { fragmentron, _, flass, _ } } } -> exit (badmsg_3)
  after 0 -> ok
  end,

  rpc:call (Other, erlang, halt, []),
  rpc:call (MoreOther, erlang, halt, [])
' -noshell -noinput -s erlang halt 2>&1 > removenode.output || { cleanup; exit 1; }

cleanup

exit 0
